<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GG分析</title>
    <!-- 引入Tailwind CSS -->
<!--    <script src="https://cdn.tailwindcss.com"></script>-->
    <!-- 引入Font Awesome -->
<!--    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">-->


    <script src="/js/ll.js"></script>
    <link href="/css/font.css" rel="stylesheet">

    <!-- 配置Tailwind自定义颜色 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#1E40AF',
                        secondary: '#3B82F6',
                        success: '#10B981',
                        danger: '#EF4444',
                        neutral: '#64748B',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .table-fixed-layout {
                table-layout: fixed;
            }
            .table-fixed-layout th,
            .table-fixed-layout td {
                border: 1px solid #ddd;  /* 细线边框 */
                padding: 8px;
            }

            .scrollbar-thin {
                scrollbar-width: thin;
            }
            .scrollbar-hide::-webkit-scrollbar {
                display: none;
            }
            .animate-fade-in {
                animation: fadeIn 0.5s ease-in-out;
            }
            .animate-slide-up {
                animation: slideUp 0.3s ease-out;
            }
            .sortable-header {
                cursor: pointer;
                position: relative;
                user-select: none;
            }
            .sortable-header:hover {
                background-color: rgba(0, 0, 0, 0.05);
            }
            .sort-indicator {
                margin-left: 5px;
                font-size: 0.8em;
                opacity: 0.7;
            }
            .filter-btn {
                @apply px-3 py-1.5 rounded-md text-sm transition-all duration-200;
            }
            .filter-btn.active {
                @apply bg-primary text-white;
            }
            .filter-btn:not(.active) {
                @apply bg-gray-100 text-gray-700 hover:bg-gray-200;
            }
        }

        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        @keyframes slideUp {
            from { transform: translateY(20px); opacity: 0; }
            to { transform: translateY(0); opacity: 1; }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans text-gray-800 m-0 p-0">
<!-- 顶部导航栏 - 添加了sticky定位实现滚动置顶 -->
<header class="bg-primary text-white shadow-md w-full sticky top-0 z-50">
    <div class="flex justify-between items-center px-4 py-4">
        <div class="flex items-center space-x-2">
            <i class="fa fa-line-chart text-2xl" aria-hidden="true"></i>
            <h1 class="text-xl md:text-2xl font-bold">GG分析</h1>
            <h2 class="text-xl md:text-2xl font-bold " style="color: red">{大盘->板块->个股||主力->热度->分时}</h2>
        </div>
        <div class="flex items-center space-x-4">
            <h1 class="text-xl md:text-2xl font-bold"><a href="/">首页</a></h1>
            <h1 class="text-xl md:text-2xl font-bold"><a href="/analysis">数据分析</a></h1>
            <h1 class="text-xl md:text-2xl font-bold"><a href="/limitup/search">涨停查询</a></h1>
            <h1 class="text-xl md:text-2xl font-bold"><a href="/gainian">概念资金</a></h1>
            <h1 class="text-xl md:text-2xl font-bold"><a href="/stocksflow">个股资金</a></h1>
            <button id="exportBtn" class="flex items-center space-x-1 px-3 py-1.5 bg-green-600 rounded-md hover:bg-green-700 transition-colors">
                <i class="fa fa-download" aria-hidden="true"></i>
                <span>导出数据</span>
            </button>
        </div>
    </div>
</header>

<!-- 主内容区 -->
<main class="w-full p-0 m-0 flex-grow flex flex-col min-h-[calc(100vh-64px)]">
    <!-- 错误提示 -->
    <!-- 错误提示：优先判断error是否存在（非null且非空） -->
    <div th:if="${error != null and error != ''}" class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
        <i class="fa fa-exclamation-circle"></i> [[${error}]]
    </div>

    <!-- 无数据提示：在无错误的前提下，判断hasData为false（处理null情况） -->
    <div th:if="${error == null or error == ''}" th:unless="${hasData != null ? hasData : false}" class="bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-3 rounded mb-4">
        <i class="fa fa-info-circle"></i> 没有找到相关股票数据
    </div>

    <!-- 筛选区域：仅当有数据且无错误时显示 -->
    <div  class="bg-white rounded-lg shadow-sm p-4 animate-fade-in sticky top-[64px] z-40">
        <div class="flex flex-col md:flex-row justify-between items-start md:items-center">
            <div class="flex items-center gap-3 mt-3 md:mt-0 flex-wrap">
                <h2 class="text-lg font-semibold text-gray-800 mb-1">资金流向汇总表</h2>
                <p class="text-lg text-gray-500" id="lastUpdateTime" style="color: red">最后更新: [[${stockFlow.createdAt}]]</p>
                <button id="addOnlySelectStock" class="text-white flex items-center space-x-1 px-3 py-2 bg-secondary rounded-md hover:bg-green-700 transition-colors" onclick="addupdateFocusStocks('2')">
                    <span>自选</span>
                </button>
                <button id="delSelectStock" class="text-white flex items-center space-x-1 px-3 py-2 bg-green-600 rounded-md hover:bg-green-700 transition-colors" onclick="removeupdateFocusStock()">
                    <span>取消关注</span>
                </button>
                <button id="addSelectStock" class="text-white flex items-center space-x-1 px-3 py-2 bg-secondary rounded-md hover:bg-green-700 transition-colors" onclick="addupdateFocusStocks('1')">
                    <span>关注选择</span>
                </button>
                <button id="SelectStock" class="text-white flex items-center space-x-1 px-3 py-2 bg-green-600 rounded-md hover:bg-green-700 transition-colors" onclick="getSelectedStockCodesJQ()">
                    <span>复制选择</span>
                </button>
                <button id="viewRisks" class="text-white flex items-center space-x-1 px-3 py-2 bg-secondary rounded-md hover:bg-green-700 transition-colors" onclick="openViewRisksStockCodesJQ('1')">
                    <span>查看风险</span>
                </button>

                <button id="refreshBtn" class="text-white flex items-center space-x-1 px-3 py-2 bg-secondary rounded-md hover:bg-green-700 transition-colors">
                    <i class="fa fa-refresh" aria-hidden="true"></i>
                    <span>刷新数据</span>
                </button>


                <div class="flex-1 min-w-[120px]">
                    <div class="flex gap-2">
                        <input type="date" id="startDate" class="w-40 px-3 py-2 border border-gray-100 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary">
                    </div>
                </div>


                <!-- 新增：一键重置过滤条件按钮 -->
                <button class="text-white flex items-center space-x-1 px-3 py-2 bg-secondary rounded-md hover:bg-green-700 transition-colors" onclick="resetAllFilters()">
                    <i class="fa fa-refresh mr-1" aria-hidden="true"></i>重置所有过滤
                </button>
            </div>
        </div>

        <div class="stats-container text-lg font-bold text-gray-700">
            总数: <span id="allCount" class="font-medium text-gray-900">[[${stockFlow.allstocks}]]</span>
            &nbsp;&nbsp;&nbsp;上涨: <span id="upCount" class="font-medium text-red-500">[[${stockFlow.stocksUP}]]</span>
            &nbsp;&nbsp;&nbsp;下跌: <span id="downCount" class="font-medium text-green-500">[[${stockFlow.stocksDown}]]</span>
            &nbsp;&nbsp;&nbsp;平盘: <span id="pinCount" class="font-medium text-gray-700">[[${stockFlow.stocksPin}]]</span>
            &nbsp;&nbsp;&nbsp;涨停: <span id="limitUpCount" class="font-medium text-red-600">[[${stockFlow.stocksLimit}]]</span>
            <br>
            关注板块: <span id="flowGainian" class="font-medium text-blue-600">[[${stockFlow.flowGainian}]]</span>
            <br>
           <span id="currentCode" class="font-medium text-red-600">[[${currentCode}]]</span>
        </div>

    </div>


    <!-- 表格容器 -->
    <div class="bg-white shadow-sm overflow-hidden animate-slide-up flex-grow flex flex-col">
        <div class="overflow-x-auto scrollbar-thin flex-grow">
            <table class="w-full table-fixed-layout h-full">
                <thead class="bg-gray-100 text-left sticky top-0 z-10">
                <tr>
                    <th class="px-2 py-2 text-xs font-medium text-gray-500 w-16" style="width: 24px;">
                        <input type="checkbox" id="select-all" class="select-all">
                    </th>
                    <th data-sort="conceptpy" class="px-4 py-3 font-semibold text-gray-700 w-24 sortable-header">日期 <span class="sort-indicator"></span></th>
                    <th data-sort="name" class="px-5 py-4 font-semibold text-gray-700 w-20 sortable-header">名称 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCapitalFlow1d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">1主力 <span class="sort-indicator"></span></th>
                    <th data-sort="capitalFlow1d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">1天总 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCapitalFlow2d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">2主力 <span class="sort-indicator"></span></th>
                    <th data-sort="capitalFlow2d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">2天总 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCapitalFlow3d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">3主力 <span class="sort-indicator"></span></th>
                    <th data-sort="capitalFlow3d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">3天总 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCapitalFlow5d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">5主力 <span class="sort-indicator"></span></th>
                    <th data-sort="capitalFlow5d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">5天总 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCapitalFlow6d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">6主力 <span class="sort-indicator"></span></th>
                    <th data-sort="capitalFlow6d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">6天总 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCapitalFlow7d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">7主力 <span class="sort-indicator"></span></th>
                    <th data-sort="capitalFlow7d" class="px-4 py-3 font-semibold text-gray-700 sortable-header">7天总 <span class="sort-indicator"></span></th>
                    <th data-sort="marketValue" class="px-4 py-3 font-semibold text-gray-700 sortable-header">市值 <span class="sort-indicator"></span></th>
                    <th data-sort="price" class="px-4 py-3 font-semibold text-gray-700 sortable-header">价格 <span class="sort-indicator"></span></th>
                    <th data-sort="mainCost" class="px-4 py-3 font-semibold text-gray-700 sortable-header">成本<span class="sort-indicator"></span></th>
                    <th data-sort="getmainCost" class="px-4 py-3 font-semibold text-gray-700 sortable-header">获利 <span class="sort-indicator"></span></th>
                    <th data-sort="changePercent" class="px-4 py-3 font-semibold text-gray-700 sortable-header">涨幅 <span class="sort-indicator"></span></th>
                    <th data-sort="volume" class="px-4 py-3 font-semibold text-gray-700 w-20 sortable-header">量百万 <span class="sort-indicator"></span></th>
                    <th data-sort="turnoverRate" class="px-4 py-3 font-semibold text-gray-700 sortable-header">换手 <span class="sort-indicator"></span></th>
                    <th data-sort="rsi6" class="px-4 py-3 font-semibold text-gray-700 sortable-header">RSI6 <span class="sort-indicator"></span></th>
                    <th data-sort="rsi12" class="px-4 py-3 font-semibold text-gray-700 sortable-header">RSI12 <span class="sort-indicator"></span></th>
                    <th data-sort="rsi24" class="px-4 py-3 font-semibold text-gray-700 sortable-header">RSI24 <span class="sort-indicator"></span></th>
<!--                    <th data-sort="concept" class="px-4 py-3 font-semibold text-gray-700 w-20 sortable-header">概念 <span class="sort-indicator"></span></th>-->
                    <th data-sort="currentRankPosition" class="px-2 py-1 font-semibold text-gray-700 w-14 sortable-header">新 <span class="sort-indicator"></span></th>
                    <th data-sort="currentOldRankPosition" class="px-2 py-1 font-semibold text-gray-700 w-14 sortable-header">旧 <span class="sort-indicator"></span></th>
                    <th data-sort="rankChange" class="px-2 py-1 font-semibold text-gray-700 w-20 sortable-header">趋势 <span class="sort-indicator"></span></th>
                </tr>
                </thead>
                <tbody id="stockTableBody">

                </tbody>
            </table>
        </div>

        <!-- 表格底部信息 -->
        <div class="px-4 py-3 bg-gray-50 border-t border-gray-200 flex justify-between items-center">
            <div class="text-sm text-gray-500">
                显示 <span id="shownCount">0</span> 条，共 <span id="totalCount">0</span> 条记录
            </div>
            <div class="flex space-x-2">
                <button id="prevPage" class="px-3 py-1 border border-gray-300 rounded-md text-sm bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                    <i class="fa fa-chevron-left" aria-hidden="true"></i> 上一页
                </button>
                <button id="nextPage" class="px-3 py-1 border border-gray-300 rounded-md text-sm bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                    下一页 <i class="fa fa-chevron-right" aria-hidden="true"></i>
                </button>
            </div>
        </div>
    </div>
</main>

<!-- 页脚 -->
<footer class="bg-gray-800 text-white py-6 w-full">
    <div class="container mx-auto px-4 text-center text-sm">
        <p>© 2025 股票资金流向统计分析系统 - 数据仅供参考</p>
    </div>
</footer>

<!-- JavaScript -->
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
<script th:inline="javascript">
    // 从后端模型获取数据并转换为JavaScript对象
    const stockData = /*[[${stockFlow.result}]]*/ [];
    const flowStock = /*[[${stockFlow.flowStock}]]*/ "";
    const todaylimitstr = /*[[${stockFlow.todaylimitstr}]]*/ "";
    const limit10dstr = /*[[${stockFlow.limit10dstr}]]*/ "";
    const searchtr = /*[[${stockFlow.searchtr}]]*/ "";
    const notlimit10dstr = /*[[${stockFlow.notlimit10dstr}]]*/ "";
    const allOptional = /*[[${stockFlow.allOptional}]]*/ "";
    const onlyFlowStock = /*[[${stockFlow.onlyFlowStock}]]*/ "";
    const flowGainian = /*[[${stockFlow.flowGainian}]]*/ "";

    // 统计数据
    const allstocks = /*[[${stockFlow.allstocks}]]*/ 0;
    const stocksUP = /*[[${stockFlow.stocksUP}]]*/ 0;
    const stocksDown = /*[[${stockFlow.stocksDown}]]*/ 0;
    let stocksPin = /*[[${stockFlow.stocksPin}]]*/ 0;
    const stocksLimit = /*[[${stockFlow.stocksLimit}]]*/ 0;

    // 查询参数
    const code = /*[[${code}]]*/ "";
    const startDate = /*[[${startDate}]]*/ "";
    const endDate = /*[[${endDate}]]*/ "";

    // 全局变量
    let filteredData = [];
    let currentPage = 1;
    const pageSize = 200;

    // 过滤条件变量
    let changePercentFilter = 'all'; // 涨幅过滤，默认为全部
    let mainCapitalFlow1dFilter = 'mainAll'; // 1天主力资金过滤，默认为全部
    let profitFilter = 'profitAll'; // 获利过滤，默认为全部

    // 排序状态变量
    let currentSortField = 'currentRankPosition'; // 默认按最新排名排序
    let currentSortDirection = 'asc'; // 默认升序

    let limitupFilter = 'all'; // 涨停过滤条件，默认为全部

    // DOM加载完成后执行
    document.addEventListener('DOMContentLoaded', function() {
        // 初始化数据
        filteredData = [...stockData];

        // 应用默认过滤和排序
        // filterByAllConditions();
        // sortData();
        updateSortIndicators();
        renderTable();
        updateLastUpdateTime();

        // 绑定事件监听器
        document.getElementById('refreshBtn').addEventListener('click', refreshData);

        document.getElementById('prevPage').addEventListener('click', goToPrevPage);
        document.getElementById('nextPage').addEventListener('click', goToNextPage);
        document.getElementById('startDate').addEventListener('change', function() {
            // 日期变化时调用接口重新获取数据
            refreshData();
        });

        // 初始化表头点击排序功能
        initSortableHeaders();

        // 全选复选框事件
        document.getElementById('select-all').addEventListener('click', setupCheckboxHandler);

        // 添加涨停过滤单选按钮事件
        document.querySelectorAll('input[name="limitupstock"]').forEach(radio => {
            radio.addEventListener('change', function() {
                limitupFilter = this.value;
                // filterByAllConditions();
                currentPage = 1;
                renderTable();
            });
        });

        const searchParams = new URLSearchParams(window.location.search);
        const startDate = searchParams.get("startDate");
        // console.log("startDate== "+startDate);
        if (startDate==='' || startDate == null){
            const today = new Date();
            document.getElementById('startDate').valueAsDate = today;
        }else{
            document.getElementById('startDate').valueAsDate = (new Date(startDate));
        }

    });

    // 设置获利过滤条件
    function setProfitFilter(filterType) {
        // 更新过滤条件
        profitFilter = filterType;

        // 应用过滤并重置分页
        // filterByAllConditions();
        currentPage = 1;
        renderTable();
    }

    // 重置所有过滤条件
    function resetAllFilters() {
        // 重置所有过滤条件变量
        changePercentFilter = 'all';
        mainCapitalFlow1dFilter = 'mainAll';
        profitFilter = 'profitAll';

        // 清空所有搜索输入框
        // 重置15天有涨停的单选按钮组（默认选中"全部"）
        document.getElementById('limitup-all').checked = true;

        // 重置所有下拉选择框为"全部"选项
        document.querySelector('select[onchange="setChangePercentFilter(this.value)"]').value = 'all';
        document.querySelector('select[onchange="setMainCapitalFlow1dFilter(this.value)"]').value = 'mainAll';
        document.querySelector('select[onchange="setProfitFilter(this.value)"]').value = 'profitAll';

        // 重新应用过滤并刷新表格
        // filterByAllConditions();
        currentPage = 1; // 重置到第一页
        renderTable();

        // 显示重置成功提示
        showResetSuccessToast();
    }

    // 显示重置成功的提示
    function showResetSuccessToast() {
        // 创建提示元素
        const toast = document.createElement('div');
        toast.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: #007bff;
        color: white;
        padding: 12px 20px;
        border-radius: 6px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.3);
        z-index: 9999;
        font-size: 12px;
        font-weight: 500;
        display: flex;
        align-items: center;
        gap: 8px;
        opacity: 0;
        transform: translateX(100%);
        transition: all 0.3s ease;
    `;

        toast.innerHTML = `
        <i class="fa fa-check-circle" aria-hidden="true"></i>
        所有过滤条件已重置
    `;

        document.body.appendChild(toast);

        // 动画显示
        setTimeout(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(0)';
        }, 100);

        // 2秒后自动隐藏
        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(100%)';
            setTimeout(() => {
                if (document.body.contains(toast)) {
                    document.body.removeChild(toast);
                }
            }, 300);
        }, 2000);
    }


    // 设置1天主力资金过滤条件
    function setMainCapitalFlow1dFilter(filterType) {
        // 更新过滤条件
        mainCapitalFlow1dFilter = filterType;

        // 应用过滤并重置分页
        // filterByAllConditions();
        currentPage = 1;
        renderTable();
    }

    // 设置涨幅过滤条件
    function setChangePercentFilter(filterType) {
        // 设置过滤条件
        changePercentFilter = filterType;

        // 应用过滤
        // filterByAllConditions();
        currentPage = 1;
        renderTable();
    }

    // 初始化表头点击排序
    function initSortableHeaders() {
        // 为所有可排序表头添加点击事件
        document.querySelectorAll('th.sortable-header').forEach(header => {
            header.addEventListener('click', handleHeaderClick);
        });
    }

    // 表头点击处理函数
    function handleHeaderClick(e) {
        const sortField = e.currentTarget.dataset.sort;

        // 如果点击的是当前排序字段，则切换排序方向
        if (currentSortField === sortField) {
            currentSortDirection = currentSortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            // 否则设置新的排序字段，默认升序
            currentSortField = sortField;
            currentSortDirection = 'desc';
        }

        // 执行排序
        sortData();

        // 更新排序指示器
        updateSortIndicators();

        // 重置分页并重新渲染
        currentPage = 1;
        renderTable();
    }

    // 更新排序指示器
    function updateSortIndicators() {
        // 清除所有指示器
        document.querySelectorAll('.sort-indicator').forEach(indicator => {
            indicator.textContent = '';
        });

        // 为当前排序字段添加指示器
        if (currentSortField) {
            const indicator = document.querySelector(`th[data-sort="${currentSortField}"] .sort-indicator`);
            indicator.textContent = currentSortDirection === 'desc' ? '↓' : '↑';
        }
    }

    // 执行数据排序
    function sortData() {
        if (!currentSortField) return;

        filteredData.sort((a, b) => {
            // 处理排名变化的特殊情况
            if (currentSortField === 'rankChange') {
                const aDiff = a.currentOldRankPosition - a.currentRankPosition;
                const bDiff = b.currentOldRankPosition - b.currentRankPosition;
                return currentSortDirection === 'asc' ? aDiff - bDiff : bDiff - aDiff;
            }

            // 处理获利排序的特殊情况
            if (currentSortField === 'getmainCost') {
                // 计算获利百分比
                const aProfit = calculateProfitPercent(a.price, a.mainCost);
                const bProfit = calculateProfitPercent(b.price, b.mainCost);
                return currentSortDirection === 'asc' ? aProfit - bProfit : bProfit - aProfit;
            }

            // 获取比较值
            let valueA = a[currentSortField];
            let valueB = b[currentSortField];

            // 处理null值
            if (valueA === null || valueA === undefined) valueA = "";
            if (valueB === null || valueB === undefined) valueB = "";

            // 数字比较
            if (!isNaN(valueA) && !isNaN(valueB)) {
                return currentSortDirection === 'asc' ? Number(valueA) - Number(valueB) : Number(valueB) - Number(valueA);
            }

            // 字符串比较
            if (typeof valueA === 'string' && typeof valueB === 'string') {
                const compareResult = valueA.localeCompare(valueB, 'zh-CN');
                return currentSortDirection === 'asc' ? compareResult : -compareResult;
            }

            // 默认比较
            return 0;
        });
    }

    // 计算获利百分比的辅助函数
    function calculateProfitPercent(price, mainCost) {
        const nowPrice = Number(price);
        const costPrice = Number(mainCost);

        if (isNaN(nowPrice) || isNaN(costPrice) || !isFinite(nowPrice) || !isFinite(costPrice) || costPrice <= 0) {
            return 0; // 无效值视为0%
        }

        return ((nowPrice - costPrice) / costPrice) * 100;
    }

    // 更新最后更新时间
    function updateLastUpdateTime() {

        // const formatTime = (createdAt) => {
        //     if (!createdAt) return '-';
        //     return new Date(createdAt).toLocaleString('zh-CN', {
        //         year: 'numeric',
        //         month: '2-digit',
        //         day: '2-digit',
        //         hour: '2-digit',
        //         minute: '2-digit',
        //         second: '2-digit'
        //     });
        // };
        // document.getElementById('lastUpdateTime').textContent = `最后更新:${formatTime(createdAt)}`;
    }

    function addupdateFocusStocks(type) {
        // 获取选中的股票代码并处理
        var focusStocks = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');

        // 验证选择
        if (!focusStocks || focusStocks.trim() === '') {
            alert('没有选择股票代码');
            return;
        }
        // 处理股票代码格式
        focusStocks = focusStocks.split('\n').join(',');

        // 根据type构建不同的请求参数
        var requestData = {};
        switch(type) {
            case '1':
                // 关注类型：传递focusStocks参数
                requestData.focusStocks = focusStocks;
                break;
            case '2':
                // 可选类型：传递allOptional参数
                requestData.allOptional = focusStocks;
                break;
            default:
                // 默认情况或错误类型处理
                alert('无效的操作类型');
                return;
        }

        // 发送AJAX请求
        $.ajax({
            url: '/sysinfo/appendBy',
            method: 'GET',
            data: requestData, // 使用根据type构建的参数
            success: function (response) {
                alert('操作成功');
            },
            error: function (xhr, status, error) {
                console.error('操作失败:', error);
                $('#loadingIndicator').removeClass('active');
            }
        });
    }


    function removeupdateFocusStock() {
        var focusStocks = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');

        if (!focusStocks || focusStocks.trim() === '') {
            alert('没有选择股票代码');
            return;
        }

        focusStocks=(focusStocks ? focusStocks.split('\n').join(',') : '');
        $.ajax({
            url: '/sysinfo/removeBy',
            method: 'GET',
            data: {
                focusStocks: focusStocks
            },
            success: function (response) {
                alert('取消关注成功');
            },
            error: function (xhr, status, error) {
                console.error('概念查询失败:', error);
                $('#loadingIndicator').removeClass('active');
            }
        });
    }

    /**
     * 批量用AI分析分析
     */
    function openViewRisksStockCodesJQ() {
        // 获取所有选中的股票代码
        const searchParams = new URLSearchParams(window.location.search);
        const code = searchParams.get("code");

        copyToClipboard(code+"这个股票有什么风险?给出详细分析。");
        window.open("https://www.doubao.com/chat/21018538323617794", '_blank');

        // 遍历选中的每个股票代码，单独打开新页面
        // selectedCodes.forEach(code => {
        //     // 为每个代码构建单独的URL（避免参数过长，且符合单股票页面设计）
        //     const targetUrl = `/stocksflow/summarystock?code=${encodeURIComponent(code)}`;
        //     // 每个股票在新标签页打开
        //
        // });
    }


    // 加载股票数据
    function loadStockData() {
        // 构建查询参数
        const startDate = document.getElementById('startDate').value;
        // const searchParams = new URLSearchParams(window.location.search);

        // 2. 获取 code 值
        // const codeValue = searchParams.get("code");
        // console.log(codeValue); // 输出："300476"

        const searchParams = new URLSearchParams(window.location.search);
        const code = searchParams.get("code");
        const params = new URLSearchParams();
        if (code) params.append('code', code);
        if (startDate) params.append('startDate', startDate);

        fetch(`/stocksflow/summarystock?${params.toString()}`)
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络响应不正常');
                }
                window.location.href = `/stocksflow/summarystock?${params.toString()}`;
            })
            .catch(error => {
                console.error('获取数据时出错:', error);
                document.getElementById('stockTableBody').innerHTML = `
                        <tr>
                            <td colspan="27" class="px-4 py-8 text-center text-red-500">
                                <p>加载数据失败: ${error.message}</p>
                                <button onclick="loadStockData()" class="mt-2 text-primary hover:underline">重试</button>
                            </td>
                        </tr>
                    `;
            });
    }


    // 刷新数据
    function refreshData() {
        const refreshBtn = document.getElementById('refreshBtn');
        const originalHtml = refreshBtn.innerHTML;

        // 显示加载状态
        refreshBtn.innerHTML = '<i class="fa fa-refresh fa-spin" aria-hidden="true"></i><span>加载中...</span>';
        refreshBtn.disabled = true;

        // 清空表格并显示加载状态
        document.getElementById('stockTableBody').innerHTML = `
                <tr>
                    <td colspan="27" class="px-4 py-8 text-center text-gray-500">
                        <div class="flex flex-col items-center">
                            <i class="fa fa-circle-o-notch fa-spin text-2xl mb-2" aria-hidden="true"></i>
                            <p>正在刷新数据...</p>
                        </div>
                    </td>
                </tr>
            `;

        loadStockData();
    }

    // 提取样式判断逻辑为独立函数
    function getStockNameStyle(stock) {
        // 先判断是否为allOptional，优先级更高
        if (allOptional && allOptional.split(',').includes(stock.code)) {
            return 'background-color: #FF0000;';
        }
        // 再判断是否为flowStock
        if (flowStock && flowStock.split(',').includes(stock.code)) {
            return 'background-color: #FFFF00;';
        }
        // 默认无特殊样式
        return '';
    }


    // 渲染表格
    function renderTable() {
        const tableBody = document.getElementById('stockTableBody');
        const startIndex = (currentPage - 1) * pageSize;
        const endIndex = Math.min(startIndex + pageSize, filteredData.length);
        const pageData = filteredData.slice(startIndex, endIndex);

        // 更新计数信息
        document.getElementById('shownCount').textContent = pageData.length;
        document.getElementById('totalCount').textContent = filteredData.length;

        // 更新分页按钮状态
        document.getElementById('prevPage').disabled = currentPage === 1;
        document.getElementById('nextPage').disabled = endIndex >= filteredData.length;

        if (pageData.length === 0) {
            tableBody.innerHTML = `<tr>
                        <td colspan="27" class="px-4 py-8 text-center text-gray-500">
                            <p>没有找到匹配的数据</p>
                        </td>
                    </tr>`;
            return;
        }

        // 生成表格内容
        let html = '';
        pageData.forEach(stock => {
            // 计算排名变化
            const rankChange = calculateRankChange(stock.currentRankPosition, stock.currentOldRankPosition);

            html += `
                <tr class="border-t border-gray-200 hover:bg-yellow-100 transition-colors">
                    <td class="px-4 py-3 text-base font-medium"><input type="checkbox" class="row-checkbox" name="select-stockCode" value="${stock.code || ''}" data-id="${stock.code || ''}"></td>
                    <td class="px-4 py-3 text-sm  font-medium">${stock.conceptpy}</td>
                    <td class="px-4 py-3 text-sm  font-medium" style="${getStockNameStyle(stock)}">
                        ${stock.name}
                    </td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.mainCapitalFlow1d/10000/10000)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCapitalFlow1d/10000/10000)}</td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.capitalFlow1d/10000/10000)}">${formatNumber(stock.capitalFlow1d/10000/10000)}</td>

                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.mainCapitalFlow2d/10000/10000)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCapitalFlow2d/10000/10000)}</td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.capitalFlow2d/10000/10000)}">${formatNumber(stock.capitalFlow2d/10000/10000)}</td>

                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.mainCapitalFlow3d/10000/10000)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCapitalFlow3d/10000/10000)}</td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.capitalFlow3d/10000/10000)}">${formatNumber(stock.capitalFlow3d/10000/10000)}</td>

                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.mainCapitalFlow5d/10000/10000)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCapitalFlow5d/10000/10000)}</td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.capitalFlow5d/10000/10000)}">${formatNumber(stock.capitalFlow5d/10000/10000)}</td>

                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.mainCapitalFlow6d/10000/10000)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCapitalFlow6d/10000/10000)}</td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.capitalFlow6d/10000/10000)}">${formatNumber(stock.capitalFlow6d/10000/10000)}</td>

                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.mainCapitalFlow7d/10000/10000)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCapitalFlow7d/10000/10000)}</td>
                    <td class="px-2 py-3 text-base  ${formatNumberClass(stock.capitalFlow7d/10000/10000)}">${formatNumber(stock.capitalFlow7d/10000/10000)}</td>

                    <td class="px-2 py-3 text-base  sm:text-right">${formatNumber(stock.marketValue/10000/10000)}</td>

                    <td class="px-4 py-3 text-base  ${formatNumberClass(stock.price)}">${formatNumber(stock.price)}</td>
                    <td class="px-4 py-3 text-base  ${formatNumberClass(stock.mainCost)}" style="background-color: #DFD3B9;">${formatNumber(stock.mainCost)}</td>
                    <td class="px-4 py-3 text-base  ${getMainProfit(stock.price, stock.mainCost).class}" style="background-color: #DFD3B9;">${getMainProfit(stock.price, stock.mainCost).html}</td>
                    <td class="px-4 py-3 text-base  ${formatNumberClass(stock.changePercent)}">${formatNumber(stock.changePercent)}%</td>

                    <td class="px-4 py-3 text-base  ">${formatNumber(stock.volume/1000000)}</td>
                    <td class="px-4 py-3 text-base  ">${formatNumber(stock.turnoverRate)}</td>
                    <td class="px-4 py-3 text-base  ">${formatNumber(stock.rsi6)}</td>
                    <td class="px-4 py-3 text-base  ">${formatNumber(stock.rsi12)}</td>
                    <td class="px-4 py-3 text-base  ">${formatNumber(stock.rsi24)}</td>

                    <td class="px-4 py-3 text-base ">${stock.currentRankPosition || '-'}</td>
                    <td class="px-4 py-3 text-base ">${stock.currentOldRankPosition || '-'}</td>
                    <td class="px-4 py-3 text-base ${rankChange.class}">${rankChange.html}</td>
                </tr>
                `;
        });
        // <td class="px-4 py-3"
        //
        // </td>

        // ${formatConcept(stock.concept).title ? `title="${formatConcept(stock.concept).title}"` : ''}>
        // ${formatConcept(stock.concept).display}

        tableBody.innerHTML = html;
    }

    // 全选/取消全选功能实现
    function setupCheckboxHandler() {
        // 获取全选复选框元素
        const selectAllCheckbox = document.getElementById('select-all');

        // 获取所有行复选框
        const rowCheckboxes = document.querySelectorAll('input[name="select-stockCode"]');

        // 全选复选框变更事件
        selectAllCheckbox.addEventListener('change', function() {
            // 将所有行复选框的状态设置为与全选复选框一致
            rowCheckboxes.forEach(checkbox => {
                checkbox.checked = this.checked;
            });
        });

        // 监听行复选框的变化，更新全选框状态
        rowCheckboxes.forEach(checkbox => {
            checkbox.addEventListener('change', function() {
                // 检查所有行复选框是否都被选中
                const allChecked = Array.from(rowCheckboxes).every(cb => cb.checked);
                selectAllCheckbox.checked = allChecked;
            });
        });
    }


    // 处理代码/名称搜索
    function handleSearch(e) {
        // filterByAllConditions();
        currentPage = 1;
        renderTable();
    }

    // 处理概念搜索
    function handleSearchGainian(e) {
        // filterByAllConditions();
        currentPage = 1;
        renderTable();
    }

    // 处理趋势变化搜索
    function handleRankChange(e) {
        // filterByAllConditions();
        currentPage = 1;
        renderTable();
    }

    // 上一页
    function goToPrevPage() {
        if (currentPage > 1) {
            currentPage--;
            renderTable();
            scrollToTableTop();
        }
    }

    // 下一页
    function goToNextPage() {
        const maxPage = Math.ceil(filteredData.length / pageSize);
        if (currentPage < maxPage) {
            currentPage++;
            renderTable();
            scrollToTableTop();
        }
    }

    // 滚动到表格顶部
    function scrollToTableTop() {
        document.querySelector('.overflow-x-auto').scrollIntoView({ behavior: 'smooth' });
    }

    // 导出数据
    function exportData() {
        if (filteredData.length === 0) {
            alert('没有可导出的数据');
            return;
        }

        // 构建CSV内容
        let csvContent = "股票代码,1天主力流入,1天总流入,2天主力流入,2天总流入,3天主力流入,3天总流入," +
            "5天主力流入,5天总流入,6天主力流入,6天总流入,7天主力流入,7天总流入,市值,价格,成本,获利(%),涨幅(%),概念,最新排名,上次排名\n";

        filteredData.forEach(stock => {
            const profitPercent = calculateProfitPercent(stock.price, stock.mainCost).toFixed(2);

            csvContent += `${stock.code},` +
                `${formatNumberForCsv(stock.mainCapitalFlow1d)},` +
                `${formatNumberForCsv(stock.capitalFlow1d)},` +
                `${formatNumberForCsv(stock.mainCapitalFlow2d)},` +
                `${formatNumberForCsv(stock.capitalFlow2d)},` +
                `${formatNumberForCsv(stock.mainCapitalFlow3d)},` +
                `${formatNumberForCsv(stock.capitalFlow3d)},` +
                `${formatNumberForCsv(stock.mainCapitalFlow5d)},` +
                `${formatNumberForCsv(stock.capitalFlow5d)},` +
                `${formatNumberForCsv(stock.mainCapitalFlow6d)},` +
                `${formatNumberForCsv(stock.capitalFlow6d)},` +
                `${formatNumberForCsv(stock.mainCapitalFlow7d)},` +
                `${formatNumberForCsv(stock.capitalFlow7d)},` +
                `${formatNumberForCsv(stock.marketValue)},` +
                `${formatNumberForCsv(stock.price)},` +
                `${formatNumberForCsv(stock.mainCost)},` +
                `${profitPercent},` +
                `${formatNumberForCsv(stock.changePercent)},` +
                `${stock.concept || ''},` +
                `${stock.currentRankPosition || ''},` +
                `${stock.currentOldRankPosition || ''}\n`;
        });

        // 创建下载链接
        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.setAttribute('href', url);

        // 生成包含当前日期的文件名
        const today = new Date();
        const fileName = `股票资金流向汇总_${today.getFullYear()}${(today.getMonth()+1).toString().padStart(2, '0')}${today.getDate().toString().padStart(2, '0')}.csv`;

        link.setAttribute('download', fileName);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }



    // 格式化数字显示，保留2位小数且不显示千位分隔符
    function formatNumber(number) {
        if (number === null || number === undefined || isNaN(number)) return '0';

        // 处理科学计数法的情况
        let num = typeof number === 'string' && number.includes('E')
            ? new Number(number)
            : Number(number);
        return num.toLocaleString('zh-CN', {
            maximumFractionDigits: 2,
            minimumFractionDigits: 2, // 确保始终显示2位小数
            useGrouping: false // 禁用千位分隔符
        });
    }

    // 为CSV格式化数字
    function formatNumberForCsv(number) {
        if (!number) return '0';
        return new Number(number).toFixed(2);
    }

    // 根据数字正负设置样式类
    function formatNumberClass(number) {
        if (!number) return '';
        const num = new Number(number);
        if (num > 0) return 'text-red-500';
        if (num < 0) return 'text-green-500';
        return '';
    }

    function formatConcept(concept) {
        // 处理空值情况
        if (!concept) return { display: '-', title: '' };

        // 处理长度限制
        if (concept.length > 13) {
            return {
                display: concept.substring(0, 13) + '...',
                title: concept
            };
        }

        // 正常显示
        return {
            display: concept,
            title: ''
        };
    }

    // 计算排名变化
    function calculateRankChange(current, old) {
        // 统一转换为数值类型，无法转换则视为无效值
        const currentRank = Number(current);
        const oldRank = Number(old);

        // 验证参数有效性（必须是有限数字且大于0，排名通常从1开始）
        if (isNaN(currentRank) || isNaN(oldRank) ||
            !isFinite(currentRank) || !isFinite(oldRank) ||
            currentRank <= 0 || oldRank <= 0) {
            return { class: 'text-gray-400', html: '-' };
        }
        const change = oldRank - currentRank;

        if (change < 0) {
            return {
                class: 'text-green-500 font-medium',
                html: `<i class="fa fa-arrow-down" aria-hidden="true"></i> ${Math.abs(change)}`
            };
        } else if (change > 0) {
            return {
                class: 'text-red-500 font-medium',
                html: `<i class="fa fa-arrow-up" aria-hidden="true"></i> ${change}`
            };
        } else {
            // 排名不变
            return {
                class: 'text-gray-500',
                html: `<i class="fa fa-minus" aria-hidden="true"></i> 0`
            };
        }
    }

    // 计算主力成本获利情况
    function getMainProfit(price, mainCost) {
        // 统一转换为数值类型
        const nowPrice = Number(price);
        const costPrice = Number(mainCost);

        // 验证参数有效性
        if (isNaN(nowPrice) || isNaN(costPrice) ||
            !isFinite(nowPrice) || !isFinite(costPrice) ||
            nowPrice <= 0 || costPrice <= 0) {
            return { class: 'text-gray-400', html: '-' };
        }

        // 计算获利金额和百分比
        const profitAmount = nowPrice - costPrice;
        const profitPercent = ((profitAmount / costPrice) * 100).toFixed(2);

        // 根据获利情况返回不同样式和内容
        if (profitAmount > 0) {
            return {
                class: 'text-red-500 font-medium',
                html: `${profitPercent}%`
            };
        } else if (profitAmount < 0) {
            return {
                class: 'text-green-500 font-medium',
                html: `${profitPercent}%`
            };
        } else {
            return {
                class: 'text-gray-500',
                html: `0.00%`
            };
        }
    }


    // 比较BigDecimal值
    function compareBigDecimals(a, b) {
        const numA = a ? new Number(a) : 0;
        const numB = b ? new Number(b) : 0;
        return numA - numB;
    }

    function getSelectedStockCodesJQ() {
        let selectCode = $('input[name="select-stockCode"]:checked').map(function() {
            return $(this).val();
        }).get().join(',');
        copyToClipboard(selectCode);
    }

    $(document).ready(function() {
        // 为表格行绑定点击事件
        $('table').on('click', 'tr', function(e) {
            // 排除直接点击复选框的情况
            if($(e.target).is('input[type="checkbox"]')) return;

            // 获取当前行的复选框
            var $checkbox = $(this).find('.row-checkbox');

            // 切换选中状态
            $checkbox.prop('checked', !$checkbox.prop('checked'));

            // 可选：添加行高亮样式
            $(this).toggleClass('active', $checkbox.prop('checked'));
        });
    });

    // 添加复制功能
    function copyToClipboard(stockCodes) {
        // 阻止事件冒泡，避免触发父元素的点击事件
        event.stopPropagation();

        if (!stockCodes || stockCodes.trim() === '') {
            alert('没有股票代码可复制');
            return;
        }

        // 使用现代浏览器的剪贴板API
        if (navigator.clipboard && window.isSecureContext) {
            navigator.clipboard.writeText(stockCodes).then(() => {
                // 显示成功提示
                showCopySuccessToast(stockCodes.split(',').length);
            }).catch(err => {
                console.error('复制失败:', err);
                fallbackCopy(stockCodes);
            });
        } else {
            // 降级方案
            fallbackCopy(stockCodes);
        }
    }

    // 降级复制方案
    function fallbackCopy(text) {
        const textArea = document.createElement('textarea');
        textArea.value = text;
        textArea.style.position = 'fixed';
        textArea.style.left = '-999999px';
        textArea.style.top = '-999999px';
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            document.execCommand('copy');
            showCopySuccessToast(text.split(',').length);
        } catch (err) {
            console.error('降级复制也失败了:', err);
            alert('复制失败，请手动复制：' + text);
        } finally {
            document.body.removeChild(textArea);
        }
    }

    // 显示复制成功的提示
    function showCopySuccessToast(count) {
        // 创建提示元素
        const toast = document.createElement('div');
        toast.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #28a745;
                color: white;
                padding: 12px 20px;
                border-radius: 6px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                z-index: 9999;
                font-size: 12px;
                font-weight: 500;
                display: flex;
                align-items: center;
                gap: 8px;
                opacity: 0;
                transform: translateX(100%);
                transition: all 0.3s ease;
            `;

        toast.innerHTML = `
                <i class="fa fa-check-circle" aria-hidden="true"></i>
                已复制 ${count} 个股票代码
            `;

        document.body.appendChild(toast);

        // 动画显示
        setTimeout(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(0)';
        }, 100);

        // 3秒后自动隐藏
        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(100%)';
            setTimeout(() => {
                if (document.body.contains(toast)) {
                    document.body.removeChild(toast);
                }
            }, 300);
        }, 3000);
    }
</script>
</body>
</html>
